<?php
namespace App\Service\OrderService\OrderNotifyService;

use App\Model\PssModel\Business;
use App\Model\PssModel\PddRepushOrder;
use App\Service\CommodityService\BbcBestGoodsService;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Task\Annotation\Task;
use App\Service\BaseService;
use App\Service\Code\Normal;
use App\Model\PssModel\TokenManage;
use App\Model\PssModel\OrderPullLog;
use App\Model\PssModel\OrderSupplier;
use Hyperf\DbConnection\Db;
use App\Model\CommodityModel\SupplierCompany;
use App\Model\PssModel\OrderSupplierGoods;
use App\Service\TaskServer\TaskWorker;
use App\Model\PssModel\OrderLogisticLog;
use App\Model\PssModel\MerchantGoodsList;
use App\Service\VendorClient\PddApi\ShopPddUserApiClient;
use App\Model\PssModel\PddToken;
use Hyperf\Utils\WaitGroup;
use function GuzzleHttp\json_decode;
use App\Model\CommodityModel\WarehouseInfo;

class PddNotifyService extends BaseService
{
    
    /**
     * @Task
     * 创建拼多多订单新版
     * @param array $param
     */
    public function orderReceiveNew( $param = [] )
    {
        $rule = [
            'bid'           => '面单申请结果',
            'orderNo'       => '拼多多单号',
            'orderCode'     => 'XP订单号不能为空'
        ];
    
        foreach ($rule as $key => $value ) {
            if( !array_key_exists($key,$param) ) {
                return Normal::returnCode(Normal::FAIL,"请求参数【{$key}】缺失");
            }
        }
    
        $bid = $param['bid'];
        $order_sn = $param['orderNo'];
        $inner_transaction_id = $param['orderCode'];
        $orderLog = OrderPullLog::instance()->info(['bid'=>$bid,'order_sn'=>$order_sn]);
        if( empty($orderLog) ) {
            return Normal::returnCode(Normal::FAIL,"订单数据未找到");
        }
        
        $contents = @json_decode($orderLog['contents'],true);
        $contents['inner_transaction_id'] = $inner_transaction_id;
        
        //判断是否有身份证号、真实姓名、支付流水号
        if( $orderLog['pdd_status'] == 0 ) 
        {
            $err_order_update = [];
            if( empty($contents['id_card_num']) ) {
                $err_order_update = [
                    'response_msg'  => '清关材料身份号为空',
                    'pull_times'    => 4,
                    'pdd_status'    => 2,
                    'md'            => time(),
                ];
                OrderPullLog::instance()->where('id',$orderLog['id'])->update($err_order_update);
                return Normal::returnCode(Normal::FAIL,"清关材料身份号为空");
            }
            if( empty($contents['id_card_name']) ) {
                $err_order_update = [
                    'response_msg'  => '清关材料姓名不能为空',
                    'pull_times'    => 4,
                    'pdd_status'    => 2,
                    'md'            => time(),
                ];
                OrderPullLog::instance()->where('id',$orderLog['id'])->update($err_order_update);
                return Normal::returnCode(Normal::FAIL,"清关材料姓名不能为空");
            }
            if( empty($contents['pay_no']) ) {
                $err_order_update = [
                    'response_msg'  => '清关材料支付流水号不能为空',
                    'pull_times'    => 4,
                    'pdd_status'    => 2,
                    'md'            => time(),
                ];
                OrderPullLog::instance()->where('id',$orderLog['id'])->update($err_order_update);
                return Normal::returnCode(Normal::FAIL,"清关材料支付流水号不能为空");
            }
        }
        
        $res = OrderPullLog::instance()->where('id',$orderLog['id'])->where('pdd_status',0)->update([
            'pdd_status'    => 1,
            'pull_times'    => 4,
            'contents'      => json_encode($contents,JSON_UNESCAPED_UNICODE),
            'md'            => time(),
        ]);
        if( $res ) {
            return Normal::returnCode(Normal::FAIL,"当前订单状态不满足出云情况");
        }
        return Normal::returnCode(Normal::SUC,"处理成功");
    }    
    
    /**
     * @Task
     * 创建拼多多订单
     * @param array $param
     */
    public function orderReceive( $param = [] )
    {
        $rule = [
            'bid'           => '面单申请结果',
            'orderNo'       => '拼多多单号',
            'orderCode'     => 'XP订单号不能为空'
        ];
        
        foreach ($rule as $key => $value ) {
            if( !array_key_exists($key,$param) ) {
                return Normal::returnCode(Normal::FAIL,"请求参数【{$key}】缺失");
            }
        }
        
        $bid = $param['bid'];
        $order_sn = $param['orderNo'];
        $inner_transaction_id = $param['orderCode'];
        $shop = PddToken::instance()->info([
            'bid'   => $bid
        ]);
        
        $PddObj = new ShopPddUserApiClient($shop);
        
        //获取请求报文
        $resQueryOrderInfo = $PddObj->queryOrderDetail([
            'order_sn'  => $order_sn,
        ]);
        
        if( $resQueryOrderInfo['code'] != Normal::SUC ) {
            return $resQueryOrderInfo;
        }
        
        if( empty($resQueryOrderInfo['data']['order_info_get_response']) || empty($resQueryOrderInfo['data']['order_info_get_response']['order_info']) ) {
            return Normal::returnCode(Normal::FAIL,"PDD参数order_info_get_response缺失");
        }
        
        $orderItem = $resQueryOrderInfo['data']['order_info_get_response']['order_info'];
        
        if( $orderItem['risk_control_status'] == 1 ) {
            return Normal::returnCode(Normal::FAIL,"未通过审核");
        }
        
        if ( !in_array($orderItem['bonded_warehouse'],$PddObj->bonded_warehouse_list) ) {
            return Normal::returnCode(Normal::FAIL,"自己的保税仓库订单");
        }
        
        //获取清关信息
        $resQueryOrderClearanceInfo = $PddObj->queryClearAnceInfoByOrderSn(['order_sn'=>$order_sn]);
        if( $resQueryOrderClearanceInfo['code'] != Normal::SUC ) {
            return $resQueryOrderClearanceInfo;
        }
        
        if( empty($resQueryOrderClearanceInfo['data']['clearance_response']) || empty($resQueryOrderClearanceInfo['data']['clearance_response']) ) {
            return Normal::returnCode(Normal::FAIL,"拼多多清关信息不能为空");
        }
        
        $orderClearance = $resQueryOrderClearanceInfo['data']['clearance_response'];
        if( empty($orderClearance['id_card_no']) || empty($orderClearance['id_card_name']) ) {
            return Normal::returnCode(Normal::FAIL,"拼多多清关信息id_card_no,id_card_name不能为空");
        }
        
        $orderItem['id_card_num']           = $orderClearance['id_card_no'];
        $orderItem['id_card_name']          = $orderClearance['id_card_name'];
        $orderItem['inner_transaction_id']  = $inner_transaction_id;
        $resWayBillInfo = $PddObj->getWaybill([$orderItem]);
        if( $resWayBillInfo['code'] != Normal::SUC || !isset($resWayBillInfo['data'][$order_sn])) {
            return $resWayBillInfo;
        }
        
        $waybill_info = $resWayBillInfo['data'][$order_sn];
        $orderItem['waybill_info'] = [
            'print_data_code'   => 200,
            'print_data_msg'    => '获取面单成功',
            'print_data'        => $waybill_info['waybill_print_data'],
            'waybill_code'      => $waybill_info['waybill_code'],
            'wp_code'           => $waybill_info['object_id'],
        ];
        return OrderPullLog::instance()->addLog([
            'bid'       => $bid,
            'order_sn'  => $order_sn,
            'contents'  => json_encode($orderItem,JSON_UNESCAPED_UNICODE),
        ]);
    }


    /**
     * 批量获取订单信息
     * @param $orderInfos
     * @return array
     */
    public function getBatchOrder($orderInfos)
    {
        //获取全部的店铺id
        $store_ids  = array_column($orderInfos,'storeId');
        $mall_ids   = array_unique($store_ids);
        
        //查下店铺信息
        $shops      = PddToken::instance()->where('auth_type',1)->whereIn('mall_id',$mall_ids)->get()->toArray();
        $shopMap    = array_column($shops,null,'mall_id');
        
        //查下渠道信息
        $bids = array_unique(array_column($shops,'bid'));
        if( empty($bids) ) {
            return Normal::returnCode(Normal::FAIL,"拼多多，云仓渠道配置数据未找到，请核对店铺id ，再三方渠道是否配置完成!");
        }
        
        $channels = Business::instance()->select(['id','id as bid','is_router_user'])->whereIn('id',$bids)->get()->toArray();
        $channelMap = array_column($channels,null,'id');
        $count = count($orderInfos);
        $wg = new WaitGroup();
        $wg->add($count);
        $result = [];
        foreach ($orderInfos as $orderInfo) 
        {
            $shop  = $shopMap[$orderInfo['storeId']];
            $orderInfo['shop'] = $shop;
            $orderInfo['binfo']  = $channelMap[$shop['bid']];
            //协程处理
            co(function () use ($wg, $orderInfo, &$result) 
            {
                $response = $this->getOrder($orderInfo);
                $msg = is_array($response) ? json_encode($response,JSON_UNESCAPED_UNICODE) : $response;
                $result[] = [
                    'storeId'   => $orderInfo['storeId'],
                    'orderSn'   => $orderInfo['orderSn'],
                    'code'      => $response['code'] ?? 0,
                    'msg'       => $msg ? $msg : '请求失败',
                    'data'      => $response['data'] ?? []
                ];
                $wg->done();
            });
        }
        $wg->wait();
        return $result;
    }


    /**
     * 获取订单信息
     * @param $param
     * @return array|mixed
     */
    public function getOrder( $param = [] )
    {
        $rule = [
            'shop'          => '店铺信息',
            'orderSn'       => '拼多多单号',
        ];

        foreach ($rule as $key => $value ) {
            if( !array_key_exists($key,$param) ) {
                return Normal::returnCode(Normal::FAIL,"请求参数【{$key}】缺失");
            }
        }

        $shop       = $param['shop'];
        $bid        = $shop['bid'];
        $binfo      = $param['binfo'];
        $order_sn   = $param['orderSn'];
        $PddObj     = new ShopPddUserApiClient($shop);

        //获取请求报文
        $resQueryOrderInfo = $PddObj->queryOrderDetail([
            'order_sn'  => $order_sn,
        ]);

        if( $resQueryOrderInfo['code'] != Normal::SUC ) {
            return $resQueryOrderInfo;
        }

        if( empty($resQueryOrderInfo['data']['order_info_get_response']) || empty($resQueryOrderInfo['data']['order_info_get_response']['order_info']) ) {
            return Normal::returnCode(Normal::FAIL,"PDD参数order_info_get_response缺失");
        }

        $orderItem = $resQueryOrderInfo['data']['order_info_get_response']['order_info'];

        if( $orderItem['risk_control_status'] == 1 ) {
            return Normal::returnCode(Normal::FAIL,"未通过审核");
        }

        //先查看商品是否授权,如果没有授权直接加入捞单池
        $item_list  = $orderItem['item_list'];

        //查询当前渠道商品是否授权
        $isNonePerfect = [];
        foreach ($item_list as $item )
        {
            $goodsSku = !empty($item['outer_id'])?$item['outer_id']:$item['outer_goods_id'];
            //如果是路由模式走供应商商品sku,否则走自编码模式
            if( $binfo['is_router_user'] == 1 ) {
                $res = BbcBestGoodsService::instance()->getBestGoodsBySupplierCodes($binfo['bid'],(string)$goodsSku);
            } else {
                $res = BbcBestGoodsService::instance()->getBestGoodsBySkuCodes($binfo['bid'],(string)$goodsSku);
            }

            if( $res['code'] != Normal::SUC ) {
                $isNonePerfect[] = $goodsSku;
            }
        }

        //组装添加记录
        $addPullOrderLog = [
            'bid'           => $bid,
            'order_sn'      => $order_sn,
            'pdd_status'    => 0,
            'response_msg'  => '获取清关信息成功',
            'contents'      => json_encode($orderItem,JSON_UNESCAPED_UNICODE),
        ];

        //更新商品未授权
        if( !empty($isNonePerfect) )
        {
            $goodsSkus = implode(",", $isNonePerfect);
            $addPullOrderLog['response_msg']    = "商品未授权【{$goodsSkus}】";
            $addPullOrderLog['pdd_status']      = 3;
            OrderPullLog::instance()->addLog($addPullOrderLog);
            return Normal::returnCode(Normal::FAIL,$addPullOrderLog['response_msg']);
        }


        //获取清关信息
        $resQueryOrderClearanceInfo = $PddObj->queryClearAnceInfoByOrderSn(['order_sn'=>$order_sn]);
        if( $resQueryOrderClearanceInfo['code'] != Normal::SUC ) {
            return $resQueryOrderClearanceInfo;
        }

        if( empty($resQueryOrderClearanceInfo['data']['clearance_response']) || empty($resQueryOrderClearanceInfo['data']['clearance_response']) ) {
            return Normal::returnCode(Normal::FAIL,"拼多多清关信息不能为空");
        }

        $orderClearance = $resQueryOrderClearanceInfo['data']['clearance_response'];
        if( empty($orderClearance['id_card_no']) || empty($orderClearance['id_card_name']) ) {
            return Normal::returnCode(Normal::FAIL,"拼多多清关信息id_card_no,id_card_name不能为空");
        }

        $orderItem['id_card_num']           = $orderClearance['id_card_no'];
        $orderItem['id_card_name']          = $orderClearance['id_card_name'];
        $resWayBillInfo = $PddObj->getWaybill([$orderItem]);
        if( $resWayBillInfo['code'] != Normal::SUC || !isset($resWayBillInfo['data'][$order_sn])) {
            return $resWayBillInfo;
        }

        $waybill_info = $resWayBillInfo['data'][$order_sn];
        $orderItem['waybill_info'] = [
            'print_data_code'   => 200,
            'print_data_msg'    => '获取面单成功',
            'print_data'        => $waybill_info['waybill_print_data'],
            'waybill_code'      => $waybill_info['waybill_code'],
            'wp_code'           => $waybill_info['object_id'],
        ];
        
        $addPullOrderLog['contents'] = json_encode($orderItem,JSON_UNESCAPED_UNICODE);
        OrderPullLog::instance()->addLog($addPullOrderLog);
        return Normal::returnCode(Normal::SUC,'获取订单成功',[
            'order_sn' => $order_sn
        ]);
    }

    
    /**
     * @Task
     * 添加拼多多订单报文数据
     * @param array $param
     */
    public function OrderPush( $param = [] )
    {
        $rule = [
            "declareResult"         => '面单申请结果',
            "bid"                   => '渠道商ID',
            "wp_code"               => '物流公司类型',
            "print_data"            => '面单信息',
            "waybill_code"          => '快递单号',
            "message"               => '申请结果',
            "orderinfo"             => '订单原始报文',
        ];
        
        foreach ($rule as $key => $value ) {
            if( !array_key_exists($key,$param) ) {
                return Normal::returnCode(Normal::FAIL,"请求参数【{$key}】缺失");
            }
        }
        
        $bid = $param['bid'];
        $tokenInfo  = TokenManage::instance()->info([
            'auth_type' => 1,
            'bid'   => $bid,
        ]);
        
        if( empty($tokenInfo) || empty($tokenInfo['bid']) ) {
            return Normal::returnCode(Normal::FAIL,"token渠道信息不存在");
        }
                
        $bid = $tokenInfo['bid'];
        $waybill_info = [
            'print_data'    => $param['print_data'],
            'waybill_code'  => $param['waybill_code'],
            'wp_code'       => $param['wp_code'],
        ];
        $pdd_order = array_merge($param['orderinfo'],[
            'waybill_info' => $waybill_info
        ]);
        
        $contents       = json_encode($pdd_order,JSON_UNESCAPED_UNICODE);
        $order_sn       = $pdd_order['order_sn'];
        $declareResult  = $param['declareResult'] == 1 ? 1 : 0;
        $insert = [
            'order_sn'          => $order_sn,
            'bid'               => $bid,
            'contents'          => $contents,
            'is_pay_declare'    => $declareResult,
            'response_msg'      => $declareResult ? '' : $param['message'],
        ];
        return OrderPullLog::instance()->addLog($insert);
    }
    
    /**
     * @Task
     * 查询清关状态回执
     * @param array $param
     */
    public function orderQueryCustomerClearance( $param = [] )
    {
        if( empty($param['bid']) ) {
            return Normal::returnCode(Normal::FAIL,"bid不能为空");
        }
        
        if( empty($param['order_sn_list']) ) {
            return Normal::returnCode(Normal::FAIL,"order_sn_list不能为空");
        }
        
        if( !is_array($param['order_sn_list']) ) {
            return Normal::returnCode(Normal::FAIL,"order_sn_list 必须为数组");
        }
        
        $order_sn_list = array_filter(array_unique($param['order_sn_list']));
        if( empty($order_sn_list) ) {
            return Normal::returnCode(Normal::FAIL,"order_sn_list不能为空");
        }
        
        $bid = $param['bid'];
        $orderList = OrderSupplier::instance()->select([
            Db::raw("CONCAT(id) as order_id"),
            'order_sn',
            Db::raw("CONCAT(company_id) as company_id"),
            "thirdpart_order_sn",
            "apply_extends"
        ])
        ->where('bid',$bid)
        ->whereIn('order_sn',$order_sn_list)
        ->where('order_push_status',1)
        ->get()
        ->toArray();
        if( empty($orderList) ) {
            return Normal::returnCode(Normal::FAIL,"暂无数据[1]");
        }
        
        $orderGroup = [];
        foreach( $orderList as $item ) {
            $orderGroup[$item['company_id']][] = $item;
            unset($item);
        }
        
        $orderIds = array_column($orderList,'order_id');
        $orderGoodsList = OrderSupplierGoods::instance()->where('bid',$bid)->whereIn('order_id',$orderIds)->get()->toArray();
        if( empty($orderGoodsList) ) {
            return Normal::returnCode(Normal::FAIL,"暂无数据[2]");
        }
        
        $orderGoodsListMap = [];
        foreach ($orderGoodsList as $item ) {
            $orderGoodsListMap[$item['order_id']][] = $item;
            unset($item);
        }
        
        $companyids = array_keys($orderGroup);
        $supplierList = SupplierCompany::instance()->getSupplierListByIds($companyids);
        if( empty($supplierList) ) {
            return Normal::returnCode(Normal::FAIL,"暂无数据[3]");
        }
        
        //根据供应商分组之后，查询对应的供应商订单报文数据
        $allReqContents = [];
        foreach ($supplierList as $value ) 
        {
            $company_id = $value['company_id'];
            if( !isset($orderGroup[$company_id]) ) {
                return Normal::returnCode(Normal::FAIL,"供应商ID『{$value['company_id']}』数据未找到，请联系管理员核对!");
            }
         
            $wareHouse = WarehouseInfo::instance()->where('SupplierID',$company_id)->first();
            if( empty($wareHouse) ) {
                return Normal::returnCode(Normal::FAIL,"供应商ID『{$value['company_id']}』仓库数据未找到，请联系管理员核对!");
            }
            
            if( empty($wareHouse['JsonBody']) ) {
                return Normal::returnCode(Normal::FAIL,"供应商ID『{$value['company_id']}』仓库数据参数不能为空，请联系管理员核对!");
            }
            
            //查询对应的容器业务信息是否存在
            $company_code = ucfirst($value['company_code']);
            $class = "App\\Service\\OrderService\\OrderRouteService\\{$company_code}";
            if( !ApplicationContext::hasContainer($class) ) {
                return Normal::returnCode(Normal::FAIL,"供应商『{$class}』未找到，请联系管理员核对!");
            }
            
            $container = ApplicationContext::getContainer();
            $executer  = $container->get($class);
            $evalSupplierOrderList = $orderGroup[$company_id];
            $res = $executer->getOrderClearanceApplyConents([
                'orderList'     => $evalSupplierOrderList,
                'orderGoods'    => $orderGoodsListMap,
                'supplier'      => $value,
                'apiBody'       => @json_decode($wareHouse['JsonBody'],true)
            ]);
            if( $res['code'] != Normal::SUC ) {
                return $res;
            }
            $allReqContents = array_merge($allReqContents,$res['data']);
        }
        
        //批量发送请求给上游供应商
        $returnResponse = [];
        $result = TaskWorker::instance()->addTask($allReqContents);
        foreach ($result as $resTask )
        {
            $request    = $resTask['request'];
            $response   = $resTask['response'];
            //查询对应的容器业务信息是否存在
            $company_code = ucfirst($request['company_code']);
            $class = "App\\Service\\OrderService\\OrderRouteService\\{$company_code}";
            if( !ApplicationContext::hasContainer($class) ) {
                return Normal::returnCode(Normal::FAIL,"供应商『{$class}』未找到，请联系管理员核对!");
            }
            
            //获取对应供应商组装的报文
            $container = ApplicationContext::getContainer();
            $executer  = $container->get($class);
            $res = $executer->getResponseCode($response,$request);
            //解析获取订单申报清关报文
            if( $res['code'] == Normal::SUC ) {
                $returnResponse[] = [
                    'code'      => Normal::SUC,
                    "msg"       => $res['msg'],
                    'order_sn'  => $request['uid'],
                    'message'   => $res['data']['orderDeclareContents'],
                ];
            } else {
                $returnResponse[] = [
                    'code'      => Normal::FAIL,
                    "msg"       => $res['msg'],
                    'order_sn'  => $request['uid'],
                    'message'   => $res['data']['orderDeclareContents'],
                ];
            }
        }
        return Normal::returnCode(Normal::SUC,"请求成功",$returnResponse);
    }
    
    /**
     * 查询订单申报清关报文
     * @param array $param
     */
    public function queryOrderDeclareList( array $param = [] )
    {
        $result_check = $this->checkQueryParam($param);
        if( $result_check['code'] != Normal::SUC ) {
            return $result_check;
        }
        return $this->getPrePareDeclareGroupListByCompanyID($param['bid'], $param['order_sn_list'],'getOrderDeclareContents');
    }

    /**
     * 查询运单申报清关报文
     * @param array $param
     */
    public function queryLogisticDeclareList(array $param = [])
    {
        $result_check = $this->checkQueryParam($param);
        if( $result_check['code'] != Normal::SUC ) {
            return $result_check;
        }
        return $this->getPrePareDeclareGroupListByCompanyID($param['bid'], $param['order_sn_list'],'getLogisticDeclareContents');
    }

    /**
     * 查询清单申报清关报文
     * @param array $param
     */
    public function queryInventoryDeclareList(array $param=[])
    {
        $result_check = $this->checkQueryParam($param);
        if( $result_check['code'] != Normal::SUC ) {
            return $result_check;
        }
        return $this->getPrePareDeclareGroupListByCompanyID($param['bid'], $param['order_sn_list'],'getInventoryDeclareContents');
        
    }

    /**
     * 查询清单申报清关报文
     * @param array $param
     */
    public function queryInventoryCancelList(array $param=[])
    {
        $result_check = $this->checkQueryParam($param);
        if( $result_check['code'] != Normal::SUC ) {
            return $result_check;
        }
        return $this->getPrePareDeclareGroupListByCompanyID($param['bid'], $param['order_sn_list'],'getInventoryCancelContents');

    }
    
    /**
     * 校验参数
     * @param array $param
     */
    public function checkQueryParam( array $param = [] )
    {
        if( empty($param['bid']) ) {
            return Normal::returnCode(Normal::FAIL,"bid不能为空");
        }
        
        if( empty($param['order_sn_list']) ) {
            return Normal::returnCode(Normal::FAIL,"order_sn_list不能为空");
        }
        
        if( !is_array($param['order_sn_list']) ) {
            return Normal::returnCode(Normal::FAIL,"order_sn_list 必须为数组");
        }
        
        $order_sn_list = array_filter(array_unique($param['order_sn_list']));
        if( empty($order_sn_list) ) {
            return Normal::returnCode(Normal::FAIL,"order_sn_list不能为空");
        }
        return Normal::returnCode(Normal::SUC,"校验通过");
    }
    
    /**
     * 获取订单分组报文
     * @param int $bid
     * @param array $orderSns
     * @param string $callMethod
     */
    public function getPrePareDeclareGroupListByCompanyID( int $bid , array $orderSns,string $callMethod )
    {
        $orderList = OrderSupplier::instance()->select([
            'order_sn',
            Db::raw("CONCAT(company_id) as company_id"),
            "thirdpart_order_sn"
        ])
        ->where('bid',$bid)
        ->whereIn('order_sn',$orderSns)
        ->where('order_push_status',1)
        ->get()
        ->toArray();
        if( empty($orderList) ) {
            return Normal::returnCode(Normal::FAIL,"暂无数据[1]");
        }
        
        $orderGroup = [];
        foreach( $orderList as $item ) {
            $orderGroup[$item['company_id']][] = $item;
            unset($item);
        }
        
        $companyids = array_keys($orderGroup);
        $supplierList = SupplierCompany::instance()->getSupplierListByIds($companyids);
        if( empty($supplierList) ) {
            return Normal::returnCode(Normal::FAIL,"暂无数据[3]");
        }
        
        $companyids = array_keys($orderGroup);
        $supplierList = SupplierCompany::instance()->getSupplierListByIds($companyids);
        if( empty($supplierList) ) {
            return Normal::returnCode(Normal::FAIL,"暂无数据[3]");
        }
        
        //根据供应商分组之后，查询对应的供应商订单报文数据
        $allReqContents = [];
        foreach ($supplierList as $supplier )
        {
            $company_id = $supplier['company_id'];
            if( empty($supplier['apiBody']) ) {
                return Normal::returnCode(Normal::FAIL,"供应商ID『{$company_id}』仓库数据参数不能为空，请联系管理员核对!");
            }
            
            //查询对应的容器业务信息是否存在
            $company_code = ucfirst($supplier['company_code']);
            $class = "App\\Service\\OrderService\\OrderRouteService\\{$company_code}";
            if( !ApplicationContext::hasContainer($class) ) {
                return Normal::returnCode(Normal::FAIL,"供应商『{$class}』未找到，请联系管理员核对!");
            }
            
            $container = ApplicationContext::getContainer();
            $executer  = $container->get($class);
            $query_result = $executer->{$callMethod}([
                'supplier'  => $supplier,
                'orderList' => $orderGroup[$company_id]
            ]);
            if( $query_result['code'] != Normal::SUC ) {
                return $query_result;
            }
            $allReqContents = array_merge($allReqContents,$query_result['data']);
        }
        
        //批量发送请求给上游供应商
        $returnResponse = [];
        $result = TaskWorker::instance()->addTask($allReqContents);
        foreach ($result as $resTask )
        {
            $request    = $resTask['request'];
            $response   = $resTask['response'];
            //查询对应的容器业务信息是否存在
            $company_code = ucfirst($request['company_code']);
            $class = "App\\Service\\OrderService\\OrderRouteService\\{$company_code}";
            if( !ApplicationContext::hasContainer($class) ) {
                return Normal::returnCode(Normal::FAIL,"供应商『{$class}』未找到，请联系管理员核对!");
            }
        
            //获取对应供应商组装的报文
            $container = ApplicationContext::getContainer();
            $executer  = $container->get($class);
            $res = $executer->getResponseCode($response,$request);
            //解析获取订单申报清关报文
            if( $res['code'] == Normal::SUC ) {
                $returnResponse[] = [
                    'code'      => Normal::SUC,
                    "msg"       => $res['msg'],
                    'order_sn'  => $request['uid'],
                    'message'   => $res['data']['orderDeclareContents'],
                ];
            } else {
                $returnResponse[] = [
                    'code'      => Normal::FAIL,
                    "msg"       => $res['msg'],
                    'order_sn'  => $request['uid'],
                    'message'   => $res['data']['orderDeclareContents'],
                ];
            }
        }
        
        return Normal::returnCode(Normal::SUC,"请求成功",$returnResponse);
    }
        
    /**
     * @Task
     * 获取云仓清关状态
     * @param array $param
     */
    public function orderQueryClearanceLogistic( $param = [] )
    {
        $rule = [
            "bid" => '商户ID',
        ];
        foreach ($rule as $key => $value ) {
            if( !isset($param[$key]) ) {
                return Normal::returnCode(Normal::FAIL,"请求参数【{$key}】缺失");
            }
        }
        
        $list = OrderLogisticLog::instance()
        ->select([
            'bid',
            'order_sn',
            'logistic_contents'
        ])
        ->where('bid',$param['bid'])
        ->where('order_logistic_status',6)
        ->where('order_status',0)
        ->get()
        ->toArray();
        if( empty($list) ) {
            return Normal::returnCode(Normal::FAIL,"暂无订单撤单报文");
        }
        
        //重组撤单报文
        $InventConntentsList = [];
        foreach ($list as $item )
        {
            $logisticContents = @json_decode($item['logistic_contents'],true);
            unset($item['logistic_contents']);
            if( !empty($logisticContents['InventConntents']) ) {
                $InventConntentsList[] = array_merge($item,['InventConntents'=>$logisticContents['InventConntents']]);
            }
            unset($item);
        }
        return Normal::returnCode(Normal::SUC,"获取成功",$InventConntentsList);
    }
    
    /**
     * @Task
     * 查询渠道授权商品
     * @param array $param
     */
    public function queryShopGoodsList( $param = [] )
    {
        if( empty($param['bid']) ) {
            return Normal::returnCode(Normal::FAIL,"bid不能为空");
        }
        
        $page   = isset($param['page']) ? $param['page']    : 1 ;
        $limit  = isset($param['limit']) ? $param['limit']  : 10 ;
        $list =  MerchantGoodsList::instance()
        ->where('bid',$param['bid'])
        ->orderBy("cd","desc")
        ->paginate($limit, ['skucode','spec_list','tax_rate','commodity_name','barcode','country_code'], 'page', $page,false)
        ->toArray();
        
        $returnPddSkuList = [];
        if( !empty($list['data']) ) {
            foreach ($list['data'] as $item ) 
            {
                $specList  = @json_decode($item['spec_list'],true);
                $storeInfo = current($specList);
                $specList  = current($storeInfo['goods_batch_list'])['spec_list'];
                $spec     = current($specList);
                $returnPddSkuList[] = [
                    'channelSkuCode'    => $item['skucode'],
                    'supplierSkuCode'   => $storeInfo['supplier_skucode'],
                    'storeAccount'      => $storeInfo['store_account'],
                    'taxRate'           => $item['tax_rate'],
                    'commodityName'     => $item['commodity_name'],
                    'specifications'    => $spec['specName'],
                    'barCode'           => $item['barcode'],
                    'measurementUnit'   => '',
                    'countryCode'       => $item['country_code']
                ];
            }
        }
        
        return Normal::returnCode(Normal::SUC,"获取成功",[
            'goodsList' => $returnPddSkuList,
            'page'      => $page,
            'limit'     => $limit,
            'total'     => $list['total']
        ]);
    }
    
    /**
     * @Task
     * 查询渠道授权商品
     * @param array $param
     */
    public function queryShopOrderList( $param = [] )
    {
        if( empty($param['bid']) ) {
            return Normal::returnCode(Normal::FAIL,"bid不能为空");
        }
        
        $page   = isset($param['page']) ? $param['page']    : 1 ;
        $limit  = isset($param['limit']) ? $param['limit']  : 10 ;
        $list =  OrderPullLog::instance()
        ->where('bid',$param['bid'])
        ->where('pdd_status',0)
        ->orderBy("id","asc")
        ->paginate($limit, ['contents','bid'], 'page', $page,false)
        ->toArray();
        
        $orderList = [];
        if( !empty($list['data']) ) {
            foreach ($list['data'] as $item )
            {
                $orderList[] = json_decode($item['contents'],true);
            }
        }
        return Normal::returnCode(Normal::SUC,"获取成功",[
            'order_list' => $orderList
        ]);
    }

    /**
     * @Task
     * 查询渠道授权商品
     * @param array $param
     */
    public function queryShopOrderListTest( $param = [] )
    {
        if( empty($param['bid']) ) {
            return Normal::returnCode(Normal::FAIL,"bid不能为空");
        }

        $page   = isset($param['page']) ? $param['page']    : 1 ;
        $limit  = isset($param['limit']) ? $param['limit']  : 10 ;
        $list =  OrderPullLog::instance()
            ->where('bid',$param['bid'])
            ->where('pdd_status',0)
            ->orderBy("id","asc")
            ->paginate($limit, ['contents','bid'], 'page', $page,false)
            ->toArray();

        $orderList = [];
        if( !empty($list['data']) ) {
            foreach ($list['data'] as $item )
            {
                $orderList[] = json_decode($item['contents'],true);
            }
        }
        return Normal::returnCode(Normal::SUC,"获取成功",[
            'order_list' => $orderList
        ]);
    }
    
    /**
     * @Task
     * 查询单个拼多多用户信息
     * @param array $param
     */
    public function queryShopSingleUser( $param = [] )
    {
        if( empty($param['bid']) ) {
            return Normal::returnCode(Normal::FAIL,"bid不能为空");
        }
        
        $singleUser = PddToken::instance()
        ->select([
            'bid',
            'mall_id',
            'token',
            'extends'
        ])
        ->where('auth_type',1)
        ->where('bid',$param['bid'])
        ->where('status',1)
        ->first();
        if( empty($singleUser) ) {
            return Normal::returnCode(Normal::FAIL,"用户数据为空");
        }
        
        return Normal::returnCode(Normal::SUC,"获取成功",$singleUser->toArray());
    }

    /**
     * @Task
     * 查询拼多多用户列表信息
     * @param array $param
     */
    public function queryShopUserList( $param = [] )
    {
        $list = PddToken::instance()
        ->select([
            'bid',
            'mall_id',
            'token',
            'extends'
        ])
        ->where('auth_type',1)
        ->where('status',1)
        ->get()
        ->toArray();
        if( empty($list) ) {
            return Normal::returnCode(Normal::FAIL,"用户数据为空");
        }
    
        return Normal::returnCode(Normal::SUC,"获取成功",[
            'shopUserList'  => $list
        ]);
    }

    /**
     * @Task 
     * 申报结果通知
     * @param array $param
     */
    public function ReceiveDeclareResult( $param = [])
    {
        if (empty($param['order_list'])){
            return Normal::returnCode(Normal::FAIL,"order_list不能为空");
        }
        $orderSns=array_column($param['order_list'],'order_sn');
        $orderList = OrderSupplier::instance()->select([
            'order_sn',
            Db::raw("CONCAT(company_id) as company_id"),
            "thirdpart_order_sn"
        ])
            ->whereIn('order_sn',$orderSns)
            ->where('order_push_status',1)
            ->get()
            ->toArray();
        if( empty($orderList) ) {
            return Normal::returnCode(Normal::FAIL,"暂无数据[1]");
        }
        $orderGroup = [];
        $orderCompanyMap=array_column($orderList,'company_id','order_sn');
        foreach( $param['order_list'] as $item) {
            $orderGroup[$orderCompanyMap[$item['order_sn']]][] = $item;
            unset($item);
        }

        $companyids = array_keys($orderGroup);
        $supplierList = SupplierCompany::instance()->getSupplierListByIds($companyids);
        if( empty($supplierList) ) {
            return Normal::returnCode(Normal::FAIL,"暂无数据[3]");
        }

        $companyids = array_keys($orderGroup);
        $supplierList = SupplierCompany::instance()->getSupplierListByIds($companyids);
        if( empty($supplierList) ) {
            return Normal::returnCode(Normal::FAIL,"暂无数据[3]");
        }
        
        //根据供应商分组之后，查询对应的供应商订单报文数据
        $allReqContents = [];
        foreach ($supplierList as $supplier )
        {
            $company_id = $supplier['company_id'];
            if( empty($supplier['apiBody']) ) {
                return Normal::returnCode(Normal::FAIL,"供应商ID『{$company_id}』仓库数据参数不能为空，请联系管理员核对!");
            }

            //查询对应的容器业务信息是否存在
            $company_code = ucfirst($supplier['company_code']);
            $class = "App\\Service\\OrderService\\OrderRouteService\\{$company_code}";
            if( !ApplicationContext::hasContainer($class) ) {
                return Normal::returnCode(Normal::FAIL,"供应商『{$class}』未找到，请联系管理员核对!");
            }

            $container = ApplicationContext::getContainer();
            $executer  = $container->get($class);
            $query_result = $executer->{__FUNCTION__}([
                'supplier'  => $supplier,
                'orderList' => $orderGroup[$company_id]
            ]);
            if( $query_result['code'] != Normal::SUC ) {
                return $query_result;
            }
            $allReqContents = array_merge($allReqContents,$query_result['data']);
        }

        //批量发送请求给上游供应商
        $returnResponse = [];
        $result = TaskWorker::instance()->addTask($allReqContents);
        foreach ($result as $resTask )
        {
            $request    = $resTask['request'];
            $response   = $resTask['response'];
            //查询对应的容器业务信息是否存在
            $company_code = ucfirst($request['company_code']);
            $class = "App\\Service\\OrderService\\OrderRouteService\\{$company_code}";
            if( !ApplicationContext::hasContainer($class) ) {
                return Normal::returnCode(Normal::FAIL,"供应商『{$class}』未找到，请联系管理员核对!");
            }

            //获取对应供应商组装的报文
            $container = ApplicationContext::getContainer();
            $executer  = $container->get($class);
            $res = $executer->getResultCode($response,$request);
            //解析获取订单申报清关报文
            if( $res['code'] == Normal::SUC ) {
                $returnResponse[] = [
                    'code'      => Normal::SUC,
                    "msg"       => $res['msg'],
                    'order_sn'  => $request['uid'],
                    'message'   => $res['data'],
                ];
            } else {
                $returnResponse[] = [
                    'code'      => Normal::FAIL,
                    "msg"       => $res['msg'],
                    'order_sn'  => $request['uid'],
                    'message'   => $res['data'],
                ];
            }
        }

        return Normal::returnCode(Normal::SUC,"请求成功",$returnResponse);
        
    }

    /**
     * @Task
     * 获取重新申报的订单
     * @param array $param
     */
    public function GetRepushOrder( $param = [] )
    {
        $limit=$param['limit']??20;
        $orders=PddRepushOrder::instance()->where(['is_take'=>0])->limit($limit)->get()->toArray();
        $order_ids=array_column($orders,'id');
        PddRepushOrder::instance()->whereIn('id',$order_ids)->update([
            'is_take'=>1
        ]);
        return Normal::returnCode(Normal::SUC,"获取成功",$orders);
    }

    /**
     * @Task
     * 重新申报订单通知
     * @param array $param
     */
    public function ReceiveRepushOrder( $param=[] )
    {
        if (empty($param['order_sn']) || empty($param['status'])){
            return Normal::returnCode(Normal::FAIL,"参数不正确");
        }
        
        $res=PddRepushOrder::instance()->insert([
            'order_sn'=>$param['order_sn'],
            'status'=>$param['status'],
            'is_take'=>0,
            'cd'=>time()
        ]);
        if (!$res){
            return Normal::returnCode(Normal::FAIL,"添加失败,系统异常");
        }
        return Normal::returnCode(Normal::SUC,"重推订单保存成功",[]);
        
    }
}